package com.crane.oss.web.support.shiro;

import com.alibaba.fastjson.JSON;
import com.crane.common.core.dto.Response;
import com.crane.common.core.exception.BasicErrorCode;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.AuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author bealon
 */
public class ApiAuthenticationFilter extends AuthenticationFilter {

    protected static List<String> allowOrigins;

    public static List<String> getAllowOrigins() {
        return allowOrigins;
    }

    public static void setAllowOrigins(List<String> allowOrigins) {
        ApiAuthenticationFilter.allowOrigins = allowOrigins;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        //判断是否授权
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isAuthenticated()) {
            HttpServletRequest httpRequest = WebUtils.toHttp(request);
            HttpServletResponse httpResponse = WebUtils.toHttp(response);
            if (httpRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
                String originHeader = httpRequest.getHeader("Origin");
//                if (allowOrigins.contains(originHeader)) {
                httpResponse.setContentType("application/json");
                httpResponse.setCharacterEncoding("utf-8");
                httpResponse.setHeader("Access-control-Allow-Origin", originHeader);
                httpResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
                httpResponse.setHeader("Access-Control-Allow-Headers",
                        "Origin,Accept,x-requested-with,content-type,X-AUTH-SESSION,Content-Security-Policy,X-Content-Type-Options,X-XSS-Protection");
                httpResponse.setHeader("Access-Control-Expose-Headers",
                        "X-AUTH-SESSION,Content-Security-Policy,X-Content-Type-Options,X-XSS-Protection");
                httpResponse.setHeader("Access-Control-Max-Age", "3600");
                httpResponse.setHeader("Content-Security-Policy",
                        "script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:");
                httpResponse.setHeader("X-Content-Type-Options", "nosniff");
                httpResponse.setHeader("X-XSS-Protection", "1; mode=block");
                // 不考虑重定向处理，如果采用hearder方式访问，重定向不会自动带上消息头。必须客户端处理。
                httpResponse.getWriter().write(JSON.toJSONString(Response.buildFailure(BasicErrorCode.SESSION_TIMEOUT)));
                return false;
//                }
            }
        }
        return true;
    }

}
